package com.engine.zx.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.engine.common.util.ServiceUtil;
import com.engine.core.impl.Service;
import com.engine.zx.entity.KqCloseSet;
import com.engine.zx.service.KqCloseAccountService;
import com.engine.workflow.entity.publicApi.PAResponseEntity;
import com.engine.workflow.entity.publicApi.ReqOperateRequestEntity;
import com.engine.workflow.publicApi.WorkflowRequestOperatePA;
import com.engine.workflow.publicApi.impl.WorkflowRequestOperatePAImpl;
import com.weaver.general.TimeUtil;
import weaver.conn.RecordSet;
import weaver.general.Util;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

public class KqCloseAccountServiceImpl extends Service implements KqCloseAccountService {

    private WorkflowRequestOperatePA getRequestOperatePA() {
        return ServiceUtil.getService(WorkflowRequestOperatePAImpl.class);
    }

    @Override
    public List<PAResponseEntity> closeAccount(Map<String, Object> param) {

        String billid = Util.null2String(param.get("billid"));
        RecordSet rs = new RecordSet();
        String subCompanyIds = "";
        String departmentIds = "";
        String startDate = "";
        String endDate = "";
        //0 发起 1 归档
        String type = Util.null2String(param.get("type"));

        rs.executeQuery("select gzfb,gzbm,ksrq,jsrq from uf_kqgzjl where id = ?",billid);
        if (rs.next()) {
             subCompanyIds = Util.null2String(rs.getString("gzfb"));
             departmentIds = Util.null2String(rs.getString("gzbm"));
             startDate = Util.null2String(rs.getString("ksrq"));
             endDate = Util.null2String(rs.getString("jsrq"));
        }

        String currentTime = TimeUtil.getCurrentTimeString();
        String lastname = user.getLastname();
        List<PAResponseEntity> paResponseEntities = new ArrayList<>();
        List<KqCloseSet> workflowList = getWorkflowList();
        List<Integer> workflowIds = workflowList.stream()
                .map(KqCloseSet::getWorkflowId)
                .collect(Collectors.toList());
        String join = CollectionUtil.join(workflowIds, ",");

        WorkflowRequestOperatePA operatePA = getRequestOperatePA();

        //1.获取系统流程数据,根据关账流程配置中流程id
        rs.executeQuery("select a.requestid,a.currentnodeid,a.workflowid,a.creater,b.formid from \n" +
                " workflow_requestbase a left join workflow_base b on a.workflowid = b.id \n" +
                " where a.workflowid in ("+join+") and a.currentnodetype not in (0,3)");

        //2.根据表单id,及配置字段参数,.获取分部or部门 开始日期和结束日期
        while (rs.next()) {
            int requestid = Util.getIntValue(rs.getString("requestid"));
            int currentnodeid = Util.getIntValue(rs.getString("currentnodeid"));
            int workflowid = Util.getIntValue(rs.getString("workflowid"));
            int creater = Util.getIntValue(rs.getString("creater"));
            int formid = Math.abs(Util.getIntValue(rs.getString("formid")));

            String tableName = "formtable_main_"+formid;
            KqCloseSet kqCloseSet = workflowList.stream()
                    .filter(k -> Objects.equals(k.getWorkflowId(), workflowid))
                    .findFirst()
                    .orElse(null);

            //3 值匹配筛选requestid
            if (checkRange(kqCloseSet,requestid,tableName,subCompanyIds,departmentIds,startDate,endDate)) {
                //4.流程干预操作
                ReqOperateRequestEntity requestParam = new ReqOperateRequestEntity();
                requestParam.setRequestId(requestid);
                requestParam.setSrc("intervenor");
                requestParam.setWorkflowId(workflowid);
                requestParam.setNodeId(currentnodeid);
                requestParam.setRemark(currentTime+"-"+lastname+"-于考勤模块统一干预处理。");
                requestParam.setEnableIntervenor(true);
                requestParam.setSubmitNodeId("0".equals(type) ? kqCloseSet.getCreateNodeId() : kqCloseSet.getEndNodeId());
                requestParam.setIntervenorid(String.valueOf(creater));
                PAResponseEntity paResponseEntity = operatePA.doIntervenor(user, requestParam);
                paResponseEntity.setExtra(requestid);
                paResponseEntities.add(paResponseEntity);
            }
        }

        //5.更新关账记录表操作者信息
        currentTime = currentTime.substring(0, currentTime.length() - 3);
        rs.executeUpdate("update uf_kqgzjl set czr = ?, zhczsj = ? where id = ?",user.getUID(),currentTime,billid);

        return paResponseEntities;
    }

    @Override
    public List<KqCloseSet> getWorkflowList() {

        List<KqCloseSet> kqCloseSets = new ArrayList<>();
        RecordSet rs = new RecordSet();
        rs.executeQuery("select id,lclj,ksrqdyzdbm,jsrqdyzdbm,ssfbdyzdbm,ssbmdyzdbm,fqjdid,gdjdid from uf_kqgzpz");
        while (rs.next()) {
            kqCloseSets.add(KqCloseSet.builder()
                    .id(Util.getIntValue(rs.getString("id")))
                    .workflowId(Util.getIntValue(rs.getString("lclj")))
                    .startDateCode(Util.null2String(rs.getString("ksrqdyzdbm")))
                    .endDateCode(Util.null2String(rs.getString("jsrqdyzdbm")))
                    .fbCode(Util.null2String(rs.getString("ssfbdyzdbm")))
                    .bmCode(Util.null2String(rs.getString("ssbmdyzdbm")))
                    .createNodeId(Util.getIntValue(rs.getString("fqjdid")))
                    .endNodeId(Util.getIntValue(rs.getString("gdjdid")))
                    .build());
        }
        return kqCloseSets;
    }

    @Override
    public Boolean checkSubmit(Map<String, Object> param) {

        String subCompanyIds = Util.null2String(param.get("subCompanyIds"));
        String departmentIds = Util.null2String(param.get("departmentIds"));
        String startDate = Util.null2String(param.get("startDate"));
        String endDate = Util.null2String(param.get("endDate"));

        boolean result = false;
        RecordSet rs = new RecordSet();

        String sql = "select id from uf_kqgzjl where ksrq <= ? and jsrq >= ? and gbzt in (1,2)";
        String sql1 = "select id from uf_kqgzjl where ksrq <= ? and jsrq >= ? and gbzt in (1,2)";

        if(!subCompanyIds.isEmpty()) {
            //like
            sql += " and gzfb is not null and (','||gzfb||','  like '%,"+subCompanyIds+",%')";
            rs.executeQuery(sql,endDate,startDate);
            result = rs.getCounts()>0;
        }

        if (!departmentIds.isEmpty() && !result) {
            sql1 += " and gzbm is not null and (','||gzbm||','  like '%,"+departmentIds+",%')";
            rs.executeQuery(sql1,endDate,startDate);
            result = rs.getCounts()>0;
        }
        rs.writeLog("KqCloseAccountServiceImpl:checkSubmit:"+sql);
        rs.writeLog("KqCloseAccountServiceImpl:checkSubmit1:"+sql1);
        return result;
    }

    /**
     * 校验流程内容 是否属于本条关账范围内
     * @return
     */
    private Boolean checkRange(KqCloseSet kqCloseSet,int requestid,String tableName,
                               String subCompanyIds,String departmentIds,String startDate,String endDate) {

        boolean result = false;

        RecordSet rs = new RecordSet();

        String sql = "select id from "+tableName+" where requestid = ? and "+kqCloseSet.getStartDateCode()+" <= ? and "+kqCloseSet.getEndDateCode()+" >= ?";
        String sql1 = "select id from "+tableName+" where requestid = ? and "+kqCloseSet.getStartDateCode()+" <= ? and "+kqCloseSet.getEndDateCode()+" >= ?";

        if(!subCompanyIds.isEmpty()) {
            String fbCode = kqCloseSet.getFbCode();
            sql += " and "+fbCode+" is not null and "+fbCode+" in ("+subCompanyIds+")";
            rs.executeQuery(sql,requestid,endDate,startDate);
            result = rs.getCounts()>0;
        }

        if (!departmentIds.isEmpty() && !result) {
            String bmCode = kqCloseSet.getBmCode();
            sql1 += " and "+bmCode+" is not null and "+bmCode+" in ("+departmentIds+")";
            rs.executeQuery(sql1,requestid,endDate,startDate);
            result = rs.getCounts()>0;
        }

        rs.writeLog("KqCloseAccountServiceImpl:checkRange:"+sql);
        rs.writeLog("KqCloseAccountServiceImpl:checkRange1:"+sql1);

         return result;

    }
}
